package com.muse.designpatterns.singleton;
/**
 * 为什么静态内部类能保证线程安全
 * 类加载的最后一个阶段 也就是类的初始化，类的初始化本质就是执行类构造器的<clinit>方法
 * 这个方法不是程序员写的，而是根据javac编译器生成的，它是由类里面所有的【静态成员的赋值语句】和【静态代码块】组成的，jvm内部会保证一个类的
 * <clinit>方法在多线程环境下被正确的加锁同步，也就是说如果多个线程同时去进行“类的初始化”，那么只有一个线程会执行<clinit>方法，其他的线程
 * 都要阻塞等待，直到这个线程执行完<clinit>方法，然后执行完后，其他线程唤醒，但不会再进入<clinit>方法，也就是说同一个加载器下，一个类只能被
 * 初始化一次
 *
 * 那么回到这个代码中，这里的静态变量的赋值操作进行编译之后实际上就是个<clinit>代码，当我们执行getInstance方法的时候，会导致
 * SingletonClassInstance类的加载，类加载的最后会执行类的初始化，但是即使在多线程情况下，
 * 这个类的初始化的<clinit>代码也只会被执行一次，所以他只会有一个实例。
 *
 * 静态内部类
 * 线程安全 调用效率高 可延迟加载
 */
public class SingletonDemo4 {
    private SingletonDemo4(){
        System.out.println("111");
    }
    /**静态内部类 */
    private static class SingletonClassInstance{
        private static final SingletonDemo4 instance = new SingletonDemo4();
    }

    /** 只有在第一次调用时才被创建，可以理解为懒加载的升级版本*/
    public static SingletonDemo4 getInstance(){
        return SingletonClassInstance.instance;
    }

}

